package com.tbit.uqbike.client.service.impl;

import cn.hutool.core.date.DateUtil;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import com.tbit.uqbike.client.dao.core.StudentAuthDao;
import com.tbit.uqbike.client.dao.core.UserAuthWhiteListDao;
import com.tbit.uqbike.client.dao.core.UserDao;
import com.tbit.uqbike.client.dao.core.UserMsgDao;
import com.tbit.uqbike.client.dao.huge.ImageDao;
import com.tbit.uqbike.client.dto.WhiteListCheckResultDTO;
import com.tbit.uqbike.client.exception.BaseException;
import com.tbit.uqbike.client.pojo.*;
import com.tbit.uqbike.client.service.StudentAuthService;
import com.tbit.uqbike.client.service.TokenService;
import com.tbit.uqbike.client.util.Assert;
import com.tbit.uqbike.client.util.DateTimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * @Author: chen
 * @Description:
 * @Date: 创建于 11:04 2019/7/18
 */
@Service("studentAuthService")
@Slf4j
public class StudentAuthServiceImpl implements StudentAuthService {

    @Autowired
    private StudentAuthDao studentAuthDao;
    @Autowired
    private ImageDao imageDao;

    @Autowired
    private UserAuthWhiteListDao userAuthWhiteListDao;

    @Autowired
    private UserDao userDao;
    @Autowired
    private UserMsgDao userMsgDao;

    @Autowired
    private TokenService tokenService;

    @Override
    public StudentAuth getStatus(Integer userId) {
        return studentAuthDao.getStatus(userId);
    }

    @Transactional
    @Override
    public String insert(StudentAuth studentAuth, MultipartFile[] imageFiles, HttpServletRequest request) {
        //todo 与认证审核存在竞争 ,对 accountId 和 studentNO 进行加锁
        String result = "";
        UserAuthWhiteList userAuthWhiteList = userAuthWhiteListDao.getCanAuthByAuthNO(studentAuth.getStudentNO(), studentAuth.getAccountId());
        if (isInWhiteList(studentAuth, userAuthWhiteList)) {
            result = handleWhiteListAuth(studentAuth);
        } else {
            result = handleNormalAuth(studentAuth, imageFiles, request);
        }
        return result;
    }

    @Override
    public WhiteListCheckResultDTO checkWhiteList(String token, String authNo) {
        Integer accountId = getUser(token).getAccountId();
        UserAuthWhiteList userAuthWhiteList = userAuthWhiteListDao.getCanAuthByAuthNO(authNo, accountId);
        if (Objects.isNull(userAuthWhiteList)) {
            return WhiteListCheckResultDTO.notFound(authNo);
        }
        int capacity = userAuthWhiteList.getCapacity();
        if (capacity == 0) {
            return WhiteListCheckResultDTO.unlimited(authNo);
        }
        int count = studentAuthDao.countCheckedApply(accountId, authNo);
        int remainCapacity = capacity - count;
        return WhiteListCheckResultDTO.of(authNo, capacity, remainCapacity);
    }

    private User getUser(String token) {
        User user = tokenService.getUser(token);
        if (user == null) {
            throw new BaseException("-20005", "用户不存在");
        }
        return user;
    }


    /**
     * 白名单用户认证
     * 需要满足以下两个条件中其中一个：
     * ① userauthwhitelist.capacity = 0
     * ② countCheckedApply < userauthwhitelist.capacity
     */
    private boolean isInWhiteList(StudentAuth studentAuth, UserAuthWhiteList userAuthWhiteList) {
        if (Objects.nonNull(userAuthWhiteList)) {
            int count = studentAuthDao.countCheckedApply(studentAuth.getAccountId(), studentAuth.getStudentNO());
            int capacity = userAuthWhiteList.getCapacity();
            return capacity == 0 || count < capacity;
        }
        return false;
    }

    private String handleWhiteListAuth(StudentAuth studentAuth) {
        String successMsg = "您已通过身份认证，请前往扫码用车";
        studentAuth.setCheckState(1);
        userDao.authStudentStatus(studentAuth.getStudentNO(), DateTimeUtil.getNowTime(), studentAuth.getUserId());
        userMsgDao.add(new UserMsg(null, 0, studentAuth.getUserId(), DateUtil.now(), null, 0, "身份认证", "您的身份认证已自动审核通过", "", ""));
        studentAuthDao.insert(studentAuth);
        return successMsg;
    }

    /**
     * 处理普通用户认证
     *
     * @param studentAuth
     * @param imageFiles
     * @param request
     * @return
     */
    private String handleNormalAuth(StudentAuth studentAuth, MultipartFile[] imageFiles, HttpServletRequest request) {
        Assert.hasLength(studentAuth.getName(), "-4001", "名称不能为空");
        String successMsg = "已提交，加急为您审核中";
        String imageIds = "";
        if (imageFiles != null && imageFiles.length > 0) {
            imageIds = handleImageFiles(imageFiles, request);
        }
        studentAuth.setImageId(imageIds);
        studentAuthDao.insert(studentAuth);
        return successMsg;
    }


    /**
     * 处理图片文件
     *
     * @param imageFiles
     * @param request
     * @return
     */
    private String handleImageFiles(MultipartFile[] imageFiles, HttpServletRequest request) {
        String imageIds = "";
        List<Image> list = new ArrayList<>();
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        if (multipartResolver.isMultipart(request)) {
            for (MultipartFile file : imageFiles) {
                if (file.getSize() > 2 * 1024 * 1024) {
                    throw new BaseException("-4003", "图片过大");
                }
                String imageId = UUID.randomUUID().toString();
                Image imageMassage = new Image();
                imageMassage.setImageId(imageId);
                imageMassage.setCreateTime(DateTimeUtil.getNowTime());
                try {
                    imageMassage.setImageContent(file.getBytes());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                String imageType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
                imageType = imageType.toLowerCase();
                imageMassage.setImageType(imageType);
                list.add(imageMassage);
                imageIds += imageId + ",";
            }
        } else {
            throw new BaseException("-4004", "请上传图片");
        }
        if (!list.isEmpty()) {
            imageDao.addBatch(list);
            imageIds = imageIds.substring(0, imageIds.length() - 1);
        } else {
            throw new BaseException("-4004", "请上传图片");
        }
        return imageIds;
    }
}
